{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"../common/rfsoc_book_banner.jpg\" alt=\"University of Strathclyde\" align=\"left\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Notebook Set A\n",
    "\n",
    "---\n",
    "\n",
    "## 01 - JupyterLab\n",
    "Welcome to the first companion notebook for the *[Software Defined Radio with Zynq UltraScale+ RFSoC](http://rfsocbook.com/)* book. We will begin by setting-up the JupyterLab environment on your computer or RFSoC development board. Then, we will explore the JupyterLab graphical user interface before investigating its basic operating principles. Finally, we will discuss how to keep the JupyterLab workspace clean by closing down unused Jupyter notebooks as you progress through them.\n",
    "\n",
    "## Table of Contents\n",
    "* [1. Introduction](#introduction)\n",
    "    * [1.1. JupyterLab Setup](#jupyterlab-setup)\n",
    "* [2. JupyterLab User Interface](#jupyterlab-user-interface)\n",
    "* [3. JupyterLab Basics](#jupyterlab-basics)\n",
    "    * [3.1. Running Code](#running-code)\n",
    "    * [3.2. Stopping the Kernel](#stopping-the-kernel)\n",
    "    * [3.3. Restarting the Kernel](#restarting-the-kernel)\n",
    "* [4. Cleaning the Workspace](#cleaning-the-workspace)\n",
    "* [5. Conclusion](#conclusion)\n",
    "\n",
    "## References\n",
    "* [1] - [Jupyter, \"Project Jupyter Website\", webpage.](https://jupyter.org/)\n",
    "* [2] - [Python, \"Python Website\", webpage.](https://www.python.org/)\n",
    "* [3] - [E. Pérez and B. E. Granger, “IPython: A System for Interactive Scientific Computing,” Computing in Science and Engineering, vol. 9, no. 3, May/June 2007, pp. 21-29.](https://doi.org/10.1109/MCSE.2007.53)\n",
    "\n",
    "## Revision\n",
    "* **v1.0** | 23/01/23 | *First Revision*\n",
    "\n",
    "---\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Introduction <a class=\"anchor\" id=\"introduction\"></a>\n",
    "Project Jupter is a non-profit, open source and community driven effort to create a web-based interactive computing environment around data science and scientific computing. Jupyter initially began as an interactive shell for Python, known as IPython. There are now over one-hundred different programming languages that have their own Jupyter kernels. In this notebook, we will introduce JupyterLab and its basic functions and features so that you can execute notebooks and run example designs.\n",
    "\n",
    "### 1.1. JupyterLab Setup <a class=\"anchor\" id=\"jupyterlab-setup\"></a>\n",
    "Jupyter has two interactive graphical environments. One is named *Jupyter Notebook* and the more recent environment is named *JupyterLab*. When executing any of the companion notebooks, the *JupyterLab* environment must be used.\n",
    "\n",
    "If you are currently using the *Jupyter Notebook* graphical environment to view this notebook, then you will need to move to *JupyterLab* to use this material.\n",
    "\n",
    "* If you are viewing this notebook on an RFSoC platform, enter the following into your web browser to launch JupyterLab:\n",
    "    * `http://<board_ip_address>:9090/lab`\n",
    "    * Replace the `<board_ip_address>` with the IP address for your RFSoC development board, such as 192.168.1.120.\n",
    "* If you are viewing this notebook on a computer and you are not using JupyterLab, then please swap to JupyterLab now. We recommend using Anaconda to launch JupyterLab."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. JupyterLab User Interface <a class=\"anchor\" id=\"jupyterlab-user-interface\"></a>\n",
    "JupyterLab is a browser-based Integrated Development Environment (IDE), which combines several useful tools into one. These include a text editor, command terminal, workspace viewer and other useful features that improve the overall user experience when developing in this environment. After setting-up JupyterLab, you will be presented with the window shown in Figure 1.\n",
    "\n",
    "<figure>\n",
    "<img src=\"./images/jupyter_lab_annotation.png\" style=\"width: 70%;\"/>\n",
    "    <figcaption><b>Figure 1: The JupyterLab window with annotations.</b></figcaption>\n",
    "</figure>\n",
    "\n",
    "There are three main areas on the JupyterLab interface. These are the menu bar, sidebar, and the main workspace (and launcher), which is in the centre of the window.\n",
    "\n",
    "The sidebar can be used to navigate the Jupyter workspace and open other notebooks. The sidebar also has a workspace manager for shutting down active notebooks and terminals, and a Jupyter extension manager.\n",
    "\n",
    "The main workspace contains interactive notebooks (such as the one you are viewing now!). You are able to use the toolbar at the top of the main workspace to run code cells, restart the Python kernel, and manipulate notebook cells."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. JupyterLab Basics <a class=\"anchor\" id=\"jupyterlab-basics\"></a>\n",
    "A Python kernel will be allocated to each notebook that you open in JupyterLab. The kernel is responsible for executing Python code for a notebook. We can use the toolbar at the top of the main workspace (shown in Figure 2) to control the kernel and command it to execute Python code cells. We can try this below.\n",
    "\n",
    "<figure>\n",
    "<img src=\"./images/jupyterlab_toolbar.png\" style=\"width: 50%;\"/>\n",
    "    <figcaption><b>Figure 2: The JupyterLab main workspace toolbar.</b></figcaption>\n",
    "</figure>\n",
    "\n",
    "### 3.1. Running Code <a class=\"anchor\" id=\"running-code\"></a>\n",
    "Running code is as simple as clicking on the code cell you want to execute and pressing the **play** button in the toolbar above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from time import sleep\n",
    "\n",
    "for i in range(10):\n",
    "    print('Hello World ', str(i))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It is also possible to execute the code in a cell by using your keyboard. Simply click on the cell and press `shift+enter` on your keyboard to execute the code cell and progress on to the next cell in the notebook. You can press `shift+enter` again to progress to the next code cell.\n",
    "\n",
    "### 3.2. Stopping the Kernel <a class=\"anchor\" id=\"stopping-the-kernel\"></a>\n",
    "The kernel can be stopped if a process is taking too long, or an error has occurred. Run the code cell below and press the **stop** button in the toolbar above to stop the code cell while it is executing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(10):\n",
    "    print('Sleeping for 2 seconds...')\n",
    "    sleep(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you stopped the kernel correctly you will have received a red dialogue box informing you that a keyboard interrupt has occurred. This output is expected when stopping the kernel while it is executing code."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3. Restarting the Kernel <a class=\"anchor\" id=\"restarting-the-kernel\"></a>\n",
    "You can restart the kernel at any time using the toolbar above. Simply click on the **circular arrow** to receive a prompt that asks if you are sure about restarting the kernel. In the prompt window, select the restart button. When the kernel is restarted, it will lose the notebook's computational state. This means that the sleep function we imported will no longer be available until it is imported again."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Cleaning the Workspace <a class=\"anchor\" id=\"cleaning-the-workspace\"></a>\n",
    "When using JupyterLab, you will open several notebooks as you navigate between demonstrators and examples. To conserve processing resources on your computer or RFSoC device, you should clean the Jupyter workspace often. When you have finished with a notebook (including this one), simply follow the steps below to shutdown active kernels.\n",
    "\n",
    "* Open the \"Running Terminal and Kernels\" tab on the left side of your screen. An example is given in Figure 3.\n",
    "\n",
    "<figure>\n",
    "<img src=\"./images/jupyterlab_select_manager.png\" style=\"width: 40%;\"/>\n",
    "    <figcaption><b>Figure 3: Selecting the \"Running Terminal and Kernels\" tab.</b></figcaption>\n",
    "</figure>\n",
    "\n",
    "* In the tab that has appears, simply click **Shutdown**, to shutdown the active kernel for that notebook. An example is shown in Figure 4.\n",
    "\n",
    "<figure>\n",
    "<img src=\"./images/jupyterlab_shutdown.png\" style=\"width: 40%;\"/>\n",
    "    <figcaption><b>Figure 4: Shutting down active kernels.</b></figcaption>\n",
    "</figure>\n",
    "\n",
    "* Notice that there are also shutdown options for active terminals. These can be shutdown too once their purpose has been fulfilled.\n",
    "\n",
    "* Now close the tab in JupyterLab where the notebooks was open to completely shutdown the notebook.\n",
    "\n",
    "Following these steps will ensure that notebooks are shutdown correctly and don't unnecessarily consume processing resources."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Conclusion\n",
    "This notebook has provided a brief introduction to the JupyterLab environment. The next notebook will introduce useful Python libraries for the manipulation, analysis, and visualisation of data."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "[Next Notebook 🚀](02_visualisation_and_analysis.ipynb)\n",
    "\n",
    "Copyright © 2023 Strathclyde Academic Media\n",
    "\n",
    "---\n",
    "---"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
